#pragma once

#include <string>
#include <vector>
#include <functional>

namespace El {
namespace Base {

/**
 * @brief 堆栈跟踪类，提供堆栈信息获取和崩溃时自动打印功能
 */
class StackTrace {
public:
    /**
     * @brief 单例模式获取实例
     * @return StackTrace& 返回StackTrace单例
     */
    static StackTrace &GetInstance();

    /**
     * @brief 初始化堆栈跟踪功能
     * @param enable_signal_handler 是否启用信号处理（默认启用）
     * @return bool 初始化是否成功
     */
    bool Start(bool enable_signal_handler = true);

    /**
     * @brief 打印当前线程的调用堆栈到标准错误输出
     */
    void PrintStackTrace();

    /**
     * @brief 获取当前堆栈的文本表示
     * @param skip_frames 要跳过的栈帧数量（默认跳过1帧，即跳过GetStackTrace自身）
     * @return std::string 堆栈的文本表示
     */
    std::string GetStackTrace(int skip_frames = 1);

    /**
     * @brief 设置自定义的崩溃处理回调函数
     * @param callback 崩溃时要调用的回调函数
     */
    void SetCrashCallback(std::function<void()> callback);

private:
    StackTrace() = default;
    ~StackTrace();
    StackTrace(const StackTrace &) = delete;
    StackTrace &operator=(const StackTrace &) = delete;

    /**
     * @brief 信号处理函数
     * @param signo 信号编号
     */
    static void SignalHandler(int signo);

    /**
     * @brief 获取单个栈帧的详细信息
     * @param addr 栈帧地址
     * @return std::string 格式化的栈帧信息
     */
    std::string GetFrameInfo(void *addr);

private:
    static constexpr int MAX_STACK_FRAMES = 64; ///< 最大栈帧数量
    bool initialized_ = false;                  ///< 是否已初始化
    std::function<void()> crash_callback_;      ///< 崩溃回调函数
};

} // namespace Base
} // namespace El
